package com.freeleaps.devops

import com.freeleaps.devops.enums.CodeLinterTypes
import com.freeleaps.devops.lint.Linter
import com.freeleaps.devops.lint.PyLint
import com.freeleaps.devops.lint.ESLint

/**
 * Lint表示静态代码检查，SAST表示安全代码扫描
 * 代码检查执行器类
 * 负责根据不同的编程语言和检查器类型执行代码质量检查
 * 支持多种代码检查器：PyLint (Python)、ESLint (JavaScript/TypeScript)
 * 提供统一的代码检查接口，支持自定义配置文件和默认配置
 */
class CodeLintExecutor {
  // Jenkins Pipeline的steps对象，用于调用Jenkins内置功能
  def steps
  // 工作空间路径，代码检查的目标目录
  def workspace
  // 代码检查配置文件路径
  def configs
  // 代码检查器类型（PyLint、ESLint等）
  def linterType
  // 组件配置对象，包含组件的所有配置信息
  def component

  /**
   * 构造函数
   * @param steps Jenkins Pipeline的steps对象
   * @param workspace 工作空间路径
   * @param configs 代码检查配置文件路径
   * @param linterType 代码检查器类型
   * @param component 组件配置对象
   */
  CodeLintExecutor(steps, workspace, configs, linterType, component) {
    this.steps = steps
    this.workspace = workspace
    this.configs = configs
    this.linterType = linterType
    this.component = component
  }

  /**
   * 执行代码检查的主要方法
   * 根据配置的检查器类型，创建相应的检查器实例并执行代码检查
   * 支持自定义配置文件和默认配置文件的自动回退机制
   */
  def execute() {
    // 检查是否提供了自定义配置文件
    if (configs == null || configs.isEmpty()) {
      steps.log.warn("CodeLintExecutor", "Not set configurations file, using default configurations as fallback")
      def configFilePath
      
      // 根据检查器类型选择默认配置文件路径
      switch (linterType) {
        case CodeLinterTypes.PYLINT:
          // Python代码检查器默认配置文件路径
          configFilePath = "com/freeleaps/devops/builtins/lint/pylint/pylintrc"
          break
        case CodeLinterTypes.ESLINT:
          // JavaScript/TypeScript代码检查器默认配置文件路径
          configFilePath = "com/freeleaps/devops/builtins/lint/eslint/eslintrc.js"
          break
        default:
          steps.log.error("CodeLintExecutor", "Unknown linter type")
          return
      }
      
      // 需要插件：Pipeline Plugin (基础插件) - 提供writeFile和libraryResource功能
      // 从Jenkins Shared Library资源中读取默认配置文件内容
      // 需要插件：Pipeline Plugin - 提供libraryResource步骤，用于访问Shared Library中的资源文件
      steps.writeFile file: "${workspace}.lintconfig", text: steps.libraryResource(configFilePath)
      // 更新配置文件路径为生成的临时文件
      configs = "${workspace}.lintconfig"
    }

    // 创建代码检查器实例
    Linter linter
    switch (linterType) {
      case CodeLinterTypes.PYLINT:
        // 创建Python代码检查器实例
        // PyLint用于Python代码的静态分析和代码质量检查
        linter = new PyLint(steps, workspace, configs)
        break
      case CodeLinterTypes.ESLINT:
        // 验证ESLint版本是否提供
        if (component.eslintVersion == null || component.eslintVersion.isEmpty()) {
          steps.log.error("CodeLintExecutor", "ESLint version is required")
          return
        }
        // 创建JavaScript/TypeScript代码检查器实例
        // ESLint用于JavaScript/TypeScript代码的静态分析和代码质量检查
        // 支持自定义ESLint版本和插件配置
        linter = new ESLint(steps, workspace, configs, component.eslintVersion, component.eslintPlugins)
        break
      default:
        // 不支持的代码检查器类型
        steps.log.error("CodeLintExecutor", "Unknown linter type")
        return
    }
    
    // 执行代码检查
    // 调用具体检查器的lint方法，执行实际的代码质量检查
    linter.lint()
  }
}